/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.module.upms.server;

import com.google.common.collect.Lists;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.DbKit;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.lambkit.Lambkit;
import com.lambkit.common.model.LambkitRecord;
import com.lambkit.common.service.LambkitApiService;
import com.lambkit.common.service.ServiceManager;
import com.lambkit.common.util.StringUtils;
import com.lambkit.core.config.ConfigManager;
import com.lambkit.db.DataSourceManager;
import com.lambkit.db.LambkitDataSource;
import com.lambkit.module.upms.server.service.*;
import com.lambkit.module.upms.server.service.impl.UpmsServerApiServiceImpl;
import com.lambkit.plugin.rpc.RpcKit;
import com.lambkit.module.upms.UpmsCache;
import com.lambkit.module.upms.UpmsConfig;
import com.lambkit.module.upms.UpmsManager;
import com.lambkit.module.upms.model.UpmsUserModel;

import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

public class UpmsServerManager {

	private static final UpmsServerManager me = new UpmsServerManager();

	public static UpmsServerManager me() {
		return me;
	}
	
	private UpmsConfig config;
	private UpmsCache cache;
	private boolean useable = false;
	
	private List<String> extUrls;
	
	public UpmsServerManager() {
		setExtUrls(Lists.newArrayList());
	}
	
	public UpmsConfig getConfig() {
		if(config==null) {
			config = Lambkit.config(UpmsConfig.class);
		}
		return config;
	}
	
	/**
	 * 对内的统一接口服务
	 * @return
	 */
	public UpmsServerApiService getUpmsApiService() {
		UpmsConfig upmsConfig = ConfigManager.me().get(UpmsConfig.class);
		if("client".equals(upmsConfig.getType())) {
			return RpcKit.obtain(UpmsServerApiService.class);
		} else {
			return Lambkit.get(UpmsServerApiService.class, UpmsServerApiServiceImpl.class);
			//return Lambkit.get(UpmsApiServiceImpl.class);
		}
    }
	
	/**
	 * pojo的接口服务
	 * @param <M>
	 * @param clazz
	 * @return
	 */
	public <M extends LambkitRecord> LambkitApiService<M> getLambkitApiService(Class<M> clazz) {
		UpmsConfig config = UpmsManager.me().getConfig();
		String dbconfig = config.getDbconfig();
		return ServiceManager.me().getApiServiceFactory().create(clazz, dbconfig);
	}
	
	/**
	 * 数据源
	 * @return
	 */
	public LambkitDataSource getDataSource() {
		UpmsConfig config = UpmsManager.me().getConfig();
		String dbconfig = config.getDbconfig();
		String configName = StrKit.notBlank(dbconfig) ? dbconfig : DbKit.MAIN_CONFIG_NAME;
		return DataSourceManager.me().getDataSource(configName);
	}
	
	public SqlPara getSqlPara(String key, Record record) {
		LambkitDataSource dataSource = getDataSource();
		if(dataSource!=null) {
			return dataSource.getDataSourcePlugin().getSqlPara(key, record);
		}
		return null;
	}

	public SqlPara getSqlPara(String key, Map data) {
		LambkitDataSource dataSource = getDataSource();
		if(dataSource!=null) {
			return dataSource.getDataSourcePlugin().getSqlPara(key, data);
		}
		return null;
	}

	public SqlPara getSqlPara(String key, Object... paras) {
		LambkitDataSource dataSource = getDataSource();
		if(dataSource!=null) {
			return dataSource.getDataSourcePlugin().getSqlPara(key, paras);
		}
		return null;
	}

	/**
	 * Upms缓存
	 * @return
	 */
	public UpmsCache getCache() {
		if(cache==null) {
			cache = new UpmsCache();
		}
		return cache;
	}

	public void setCache(UpmsCache cache) {
		this.cache = cache;
	}
	
	public UpmsUserModel currentUser() {
		// 登录信息
        Subject subject = SecurityUtils.getSubject();
        String username = (String) subject.getPrincipal();
        if(StrKit.notBlank(username)) {
        	UpmsUserModel upmsUser = UpmsServerManager.me().getUpmsApiService().selectUpmsUserByUsername(username);
            return upmsUser;
        }
        return null;
	}
	
	public UpmsUserModel getUser(String sessionId) {
		// 判断是否已登录，如果已登录，则回跳
        String code = getCache().getSession(sessionId);
        // code校验值
        if (StringUtils.isNotBlank(code) && code.startsWith(sessionId + "&")) {
        	//String username = code.substring(code.lastIndexOf("&"));
            String username = code.replace(sessionId + "&", "");
            if(StrKit.notBlank(username)) {
            	UpmsUserModel upmsUser = UpmsServerManager.me().getUpmsApiService().selectUpmsUserByUsername(username);
                return upmsUser;
            }
        }
        return null;
	}
	
	/**
	 * 验证url是否需要upms拦截
	 * @param target
	 * @return
	 */
	public boolean validateUrl(String target) {
		for (String url : extUrls) {
			if(target.startsWith(url)) {
				return false;
			}
		}
		return true;
	}
	
	public void addExtUrl(String url) {
		extUrls.add(url);
	}

	public List<String> getExtUrls() {
		return extUrls;
	}

	public void setExtUrls(List<String> extUrls) {
		this.extUrls = extUrls;
	}

	public boolean isUseable() {
		return useable;
	}

	public void setUseable(boolean useable) {
		this.useable = useable;
	}

	public boolean hasAnyRoles(UpmsUserModel user, String roleNames) {
		return getUpmsApiService().hasAnyRoles(user.getUserId(), roleNames);
	}

}
